package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
)

func main() {
	// 1. 打开网络设备（或pcap文件）进行捕获
	// 注意：替换为你的网络接口名（如 "eth0"、"en0"）
	iface := "ens192"
	handle, err := pcap.OpenLive(iface, 1600, true, pcap.BlockForever)
	if err != nil {
		log.Fatalf("无法打开设备 %s: %v", iface, err)
	}
	defer handle.Close()

	// 2. 设置过滤器：只捕获TCP 80端口（HTTP）的数据包
	if err := handle.SetBPFFilter("tcp"); err != nil {
		log.Fatalf("过滤器设置失败: %v", err)
	}

	// 3. 循环捕获并解析数据包
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range packetSource.Packets() {
		// 解析链路层（Ethernet）
		ethLayer := packet.Layer(layers.LayerTypeEthernet)
		if ethLayer == nil {
			continue
		}
		eth := ethLayer.(*layers.Ethernet)

		// 解析网络层（IP）
		ipLayer := packet.Layer(layers.LayerTypeIPv4)
		if ipLayer == nil {
			continue // 忽略非IPv4数据包
		}
		ip := ipLayer.(*layers.IPv4)

		// 解析传输层（TCP）
		tcpLayer := packet.Layer(layers.LayerTypeTCP)
		if tcpLayer == nil {
			continue
		}
		tcp := tcpLayer.(*layers.TCP)

		// 4. 提取应用层数据（HTTP）
		applicationLayer := packet.ApplicationLayer()
		if applicationLayer == nil {
			continue // 无应用层数据
		}
		payload := applicationLayer.Payload()

		// 5. DPI分析：解析HTTP请求（简单示例）
		if len(payload) > 0 {
			// 提取HTTP方法（如 GET、POST）
			methodEnd := strings.Index(string(payload), " ")
			if methodEnd > 0 && methodEnd < 10 { // 简单校验
				method := string(payload[:methodEnd])

				// 提取URL路径（如 /index.html）
				pathStart := methodEnd + 1
				pathEnd := strings.Index(string(payload[pathStart:]), " ")
				if pathEnd > 0 {
					path := string(payload[pathStart : pathStart+pathEnd])

					// 提取Host头（如 example.com）
					hostStart := strings.Index(string(payload), "Host: ")
					var host string
					if hostStart > 0 {
						hostEnd := strings.Index(string(payload[hostStart:]), "\r\n")
						if hostEnd > 0 {
							host = string(payload[hostStart+6 : hostStart+hostEnd])
						}
					}

					// 输出DPI结果
					fmt.Printf("[DPI分析]\n")
					fmt.Printf("  源ETH: %s:%d\n", eth.SrcMAC, eth.SrcMAC)
					fmt.Printf("  源IP: %s:%d\n", ip.SrcIP, tcp.SrcPort)
					fmt.Printf("  目标IP: %s:%d\n", ip.DstIP, tcp.DstPort)
					fmt.Printf("  HTTP方法: %s\n", method)
					fmt.Printf("  URL: http://%s%s\n", host, path)
					fmt.Printf("-------------------------\n")
				}
			}
		}
	}
}
